<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数独小游戏</title>
    <link rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #6a93cb, #a4bfef);
            color: #333;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        
        .container {
            background-color: #ffffff;
            border-radius: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
            width: 100%;
            max-width: 600px;
            padding: 30px;
            text-align: center;
        }
        
        h1 {
            font-size: 36px;
            margin-bottom: 25px;
            color: #2c3e50;
            text-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .difficulty {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 25px;
            flex-wrap: wrap;
        }
        
        .difficulty-btn {
            padding: 12px 25px;
            font-size: 18px;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-weight: bold;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        
        .difficulty-btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
        }
        
        .difficulty-btn:active {
            transform: translateY(1px);
        }
        
        .easy {
            background: linear-gradient(to right, #4CAF50, #8BC34A);
            color: white;
        }
        
        .medium {
            background: linear-gradient(to right, #FF9800, #FFC107);
            color: white;
        }
        
        .hard {
            background: linear-gradient(to right, #F44336, #E91E63);
            color: white;
        }
        
        .game-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 20px;
            padding: 0 10px;
            font-size: 18px;
            font-weight: bold;
            color: #2c3e50;
        }
        
        .sudoku-container {
            display: inline-block;
            margin-bottom: 25px;
            border: 3px solid #2c3e50;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }
        
        .sudoku-grid {
            border-collapse: collapse;
            background-color: white;
        }
        
        .sudoku-grid td {
            width: 45px;
            height: 45px;
            border: 2px solid #cccccc;
            text-align: center;
            font-size: 24px;
            font-weight: bold;
            position: relative;
            transition: background-color 0.3s;
        }
        
        .sudoku-grid input {
            width: 100%;
            height: 100%;
            border: none;
            text-align: center;
            font-size: 24px;
            font-weight: bold;
            background: transparent;
            color: #3498db;
            outline: none;
        }
        
        .sudoku-grid input:focus {
            background-color: #f0f7ff;
        }
        
        /* 加粗的边框 */
        .sudoku-grid tr:nth-child(3n) td {
            border-bottom: 3px solid #2c3e50;
        }
        
        .sudoku-grid tr td:nth-child(3n) {
            border-right: 3px solid #2c3e50;
        }
        
        .sudoku-grid tr:first-child td {
            border-top: 3px solid #2c3e50;
        }
        
        .sudoku-grid tr td:first-child {
            border-left: 3px solid #2c3e50;
        }
        
        /* 预填充的单元格 */
        .prefilled {
            background-color: #f8f9fa;
            color: #2c3e50;
        }
        
        .prefilled input {
            color: #2c3e50;
            font-weight: bold;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
        }
        
        .control-btn {
            padding: 14px 30px;
            font-size: 18px;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-weight: bold;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .check-btn {
            background: linear-gradient(to right, #3498db, #1abc9c);
            color: white;
        }
        
        .restart-btn {
            background: linear-gradient(to right, #9b59b6, #8e44ad);
            color: white;
        }
        
        .control-btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
        }
        
        .control-btn:active {
            transform: translateY(1px);
        }
        
        /* 验证结果样式 */
        .correct {
            background-color: #d4edda !important;
            animation: pulseGreen 0.5s;
        }
        
        .incorrect {
            background-color: #f8d7da !important;
            animation: pulseRed 0.5s;
        }
        
        @keyframes pulseGreen {
            0% { background-color: white; }
            50% { background-color: #c3e6cb; }
            100% { background-color: #d4edda; }
        }
        
        @keyframes pulseRed {
            0% { background-color: white; }
            50% { background-color: #f5c6cb; }
            100% { background-color: #f8d7da; }
        }
        
        /* 响应式设计 */
        @media (max-width: 600px) {
            .container {
                padding: 20px 15px;
            }
            
            h1 {
                font-size: 28px;
            }
            
            .difficulty-btn {
                padding: 10px 15px;
                font-size: 16px;
            }
            
            .sudoku-grid td {
                width: 35px;
                height: 35px;
                font-size: 20px;
            }
            
            .sudoku-grid input {
                font-size: 20px;
            }
            
            .control-btn {
                padding: 12px 20px;
                font-size: 16px;
            }
            
            .game-info {
                flex-direction: column;
                gap: 10px;
                align-items: center;
            }
        }
        
        @media (max-width: 400px) {
            .sudoku-grid td {
                width: 30px;
                height: 30px;
                font-size: 18px;
            }
            
            .sudoku-grid input {
                font-size: 18px;
            }
            
            .difficulty {
                gap: 10px;
            }
            
            .difficulty-btn {
                padding: 8px 12px;
                font-size: 14px;
            }
            
            .control-btn {
                padding: 10px 15px;
                font-size: 14px;
            }
        }
        
        .instructions {
            margin-top: 25px;
            padding: 15px;
            background-color: #f8f9fa;
            border-radius: 10px;
            text-align: left;
            font-size: 14px;
            color: #495057;
        }
        
        .instructions h3 {
            margin-bottom: 10px;
            color: #2c3e50;
            text-align: center;
        }
        
        .instructions ul {
            padding-left: 20px;
        }
        
        .instructions li {
            margin-bottom: 8px;
        }
        
        .highlight {
            background-color: #fffacd;
            padding: 2px 5px;
            border-radius: 3px;
        }
    </style>
</head>
<body>
<div class="container">
    <h1><i class="fas fa-puzzle-piece"></i> 数独小游戏</h1>

    <div class="difficulty">
        <button class="difficulty-btn easy" id="easyBtn">
            <i class="fas fa-seedling"></i> 简单
        </button>
        <button class="difficulty-btn medium" id="mediumBtn">
            <i class="fas fa-balance-scale"></i> 中等
        </button>
        <button class="difficulty-btn hard" id="hardBtn">
            <i class="fas fa-fire"></i> 困难
        </button>
    </div>

    <div class="game-info">
        <div id="difficultyDisplay">难度: <span class="highlight">未选择</span></div>
        <div id="timer">时间: <span class="highlight">00:00</span></div>
    </div>

    <div class="sudoku-container">
        <table class="sudoku-grid" id="sudokuGrid">
            <!-- 表格将通过JavaScript生成 -->
        </table>
    </div>

    <div class="controls">
        <button class="control-btn check-btn" id="checkBtn">
            <i class="fas fa-check-circle"></i> 检查答案
        </button>
        <button class="control-btn restart-btn" id="restartBtn">
            <i class="fas fa-redo-alt"></i> 重新开始
        </button>
    </div>

    <div class="instructions">
        <h3><i class="fas fa-info-circle"></i> 游戏说明</h3>
        <ul>
            <li>数独规则：在9×9的网格中填入数字1-9，使每行、每列和每个3×3子网格中都包含1-9且不重复</li>
            <li>选择难度后，游戏会自动生成数独谜题</li>
            <li><span class="highlight">灰色单元格</span>是预填数字，不可更改</li>
            <li>点击<span class="highlight">"检查答案"</span>验证您的解答</li>
            <li>绿色单元格表示正确，红色表示错误</li>
            <li>点击<span class="highlight">"重新开始"</span>可以重置当前谜题</li>
        </ul>
    </div>
</div>

<script>
    document.addEventListener('DOMContentLoaded', function() {
        // 获取DOM元素
        const sudokuGrid = document.getElementById('sudokuGrid');
        const easyBtn = document.getElementById('easyBtn');
        const mediumBtn = document.getElementById('mediumBtn');
        const hardBtn = document.getElementById('hardBtn');
        const checkBtn = document.getElementById('checkBtn');
        const restartBtn = document.getElementById('restartBtn');
        const difficultyDisplay = document.getElementById('difficultyDisplay');
        const timerDisplay = document.getElementById('timer').querySelector('.highlight');

        // 游戏状态
        let currentDifficulty = null;
        let initialBoard = [];
        let currentBoard = [];
        let startTime = null;
        let timerInterval = null;

        // 预定义数独谜题（简单、中等、困难）
        const puzzles = {
            easy: {
                puzzle: [
                    [5, 3, 0, 0, 7, 0, 0, 0, 0],
                    [6, 0, 0, 1, 9, 5, 0, 0, 0],
                    [0, 9, 8, 0, 0, 0, 0, 6, 0],
                    [8, 0, 0, 0, 6, 0, 0, 0, 3],
                    [4, 0, 0, 8, 0, 3, 0, 0, 1],
                    [7, 0, 0, 0, 2, 0, 0, 0, 6],
                    [0, 6, 0, 0, 0, 0, 2, 8, 0],
                    [0, 0, 0, 4, 1, 9, 0, 0, 5],
                    [0, 0, 0, 0, 8, 0, 0, 7, 9]
                ],
                solution: [
                    [5, 3, 4, 6, 7, 8, 9, 1, 2],
                    [6, 7, 2, 1, 9, 5, 3, 4, 8],
                    [1, 9, 8, 3, 4, 2, 5, 6, 7],
                    [8, 5, 9, 7, 6, 1, 4, 2, 3],
                    [4, 2, 6, 8, 5, 3, 7, 9, 1],
                    [7, 1, 3, 9, 2, 4, 8, 5, 6],
                    [9, 6, 1, 5, 3, 7, 2, 8, 4],
                    [2, 8, 7, 4, 1, 9, 6, 3, 5],
                    [3, 4, 5, 2, 8, 6, 1, 7, 9]
                ]
            },
            medium: {
                puzzle: [
                    [0, 0, 0, 2, 6, 0, 7, 0, 1],
                    [6, 8, 0, 0, 7, 0, 0, 9, 0],
                    [1, 9, 0, 0, 0, 4, 5, 0, 0],
                    [8, 2, 0, 1, 0, 0, 0, 4, 0],
                    [0, 0, 4, 6, 0, 2, 9, 0, 0],
                    [0, 5, 0, 0, 0, 3, 0, 2, 8],
                    [0, 0, 9, 3, 0, 0, 0, 7, 4],
                    [0, 4, 0, 0, 5, 0, 0, 3, 6],
                    [7, 0, 3, 0, 1, 8, 0, 0, 0]
                ],
                solution: [
                    [4, 3, 5, 2, 6, 9, 7, 8, 1],
                    [6, 8, 2, 5, 7, 1, 4, 9, 3],
                    [1, 9, 7, 8, 3, 4, 5, 6, 2],
                    [8, 2, 6, 1, 9, 5, 3, 4, 7],
                    [3, 7, 4, 6, 8, 2, 9, 1, 5],
                    [9, 5, 1, 7, 4, 3, 6, 2, 8],
                    [5, 1, 9, 3, 2, 6, 8, 7, 4],
                    [2, 4, 8, 9, 5, 7, 1, 3, 6],
                    [7, 6, 3, 4, 1, 8, 2, 5, 9]
                ]
            },
            hard: {
                puzzle: [
                    [0, 0, 0, 6, 0, 0, 4, 0, 0],
                    [7, 0, 0, 0, 0, 3, 6, 0, 0],
                    [0, 0, 0, 0, 9, 1, 0, 8, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 5, 0, 1, 8, 0, 0, 0, 3],
                    [0, 0, 0, 3, 0, 6, 0, 4, 5],
                    [0, 4, 0, 2, 0, 0, 0, 6, 0],
                    [9, 0, 3, 0, 0, 0, 0, 0, 0],
                    [0, 2, 0, 0, 0, 0, 1, 0, 0]
                ],
                solution: [
                    [5, 8, 1, 6, 7, 2, 4, 3, 9],
                    [7, 9, 2, 8, 4, 3, 6, 5, 1],
                    [3, 6, 4, 5, 9, 1, 7, 8, 2],
                    [4, 3, 8, 9, 5, 7, 2, 1, 6],
                    [2, 5, 6, 1, 8, 4, 9, 7, 3],
                    [1, 7, 9, 3, 2, 6, 8, 4, 5],
                    [8, 4, 5, 2, 1, 9, 3, 6, 7],
                    [9, 1, 3, 7, 6, 8, 5, 2, 4],
                    [6, 2, 7, 4, 3, 5, 1, 9, 8]
                ]
            }
        };

        // 初始化数独表格
        function initGrid() {
            sudokuGrid.innerHTML = '';
            for (let i = 0; i < 9; i++) {
                const row = document.createElement('tr');
                for (let j = 0; j < 9; j++) {
                    const cell = document.createElement('td');
                    const input = document.createElement('input');
                    input.type = 'text';
                    input.maxLength = 1;
                    input.dataset.row = i;
                    input.dataset.col = j;

                    // 只允许输入数字
                    input.addEventListener('input', function(e) {
                        this.value = this.value.replace(/[^1-9]/g, '');
                    });

                    cell.appendChild(input);
                    row.appendChild(cell);
                }
                sudokuGrid.appendChild(row);
            }
        }

        // 开始游戏
        function startGame(difficulty) {
            currentDifficulty = difficulty;
            const puzzle = puzzles[difficulty].puzzle;
            initialBoard = JSON.parse(JSON.stringify(puzzle));
            currentBoard = JSON.parse(JSON.stringify(puzzle));

            // 更新显示
            difficultyDisplay.innerHTML = `难度: <span class="highlight">${getDifficultyName(difficulty)}</span>`;

            // 填充表格
            for (let i = 0; i < 9; i++) {
                for (let j = 0; j < 9; j++) {
                    const cell = sudokuGrid.rows[i].cells[j];
                    const input = cell.querySelector('input');

                    if (puzzle[i][j] !== 0) {
                        input.value = puzzle[i][j];
                        input.readOnly = true;
                        cell.classList.add('prefilled');
                    } else {
                        input.value = '';
                        input.readOnly = false;
                        cell.classList.remove('prefilled');
                    }

                    // 重置验证样式
                    cell.classList.remove('correct', 'incorrect');
                }
            }

            // 启动计时器
            startTimer();
        }

        // 获取难度名称
        function getDifficultyName(difficulty) {
            switch(difficulty) {
                case 'easy': return '简单';
                case 'medium': return '中等';
                case 'hard': return '困难';
                default: return '未知';
            }
        }

        // 开始计时
        function startTimer() {
            // 清除现有计时器
            if (timerInterval) {
                clearInterval(timerInterval);
            }

            startTime = new Date();
            timerInterval = setInterval(updateTimer, 1000);
            updateTimer();
        }

        // 更新计时器显示
        function updateTimer() {
            const now = new Date();
            const elapsed = Math.floor((now - startTime) / 1000);
            const minutes = Math.floor(elapsed / 60).toString().padStart(2, '0');
            const seconds = (elapsed % 60).toString().padStart(2, '0');
            timerDisplay.textContent = `${minutes}:${seconds}`;
        }

        // 检查答案
        function checkSolution() {
            if (!currentDifficulty) {
                alert('请先选择难度开始游戏！');
                return;
            }

            // 获取用户输入
            for (let i = 0; i < 9; i++) {
                for (let j = 0; j < 9; j++) {
                    const cell = sudokuGrid.rows[i].cells[j];
                    const input = cell.querySelector('input');

                    if (!input.readOnly) {
                        const value = input.value ? parseInt(input.value) : 0;
                        currentBoard[i][j] = value;
                    }
                }
            }

            // 验证答案
            const solution = puzzles[currentDifficulty].solution;
            let allCorrect = true;

            for (let i = 0; i < 9; i++) {
                for (let j = 0; j < 9; j++) {
                    const cell = sudokuGrid.rows[i].cells[j];

                    // 跳过预填单元格
                    if (initialBoard[i][j] !== 0) continue;

                    // 移除之前的验证样式
                    cell.classList.remove('correct', 'incorrect');

                    if (currentBoard[i][j] === solution[i][j]) {
                        cell.classList.add('correct');
                    } else {
                        cell.classList.add('incorrect');
                        allCorrect = false;
                    }
                }
            }

            // 检查行、列和子网格的重复
            checkDuplicates();

            if (allCorrect) {
                setTimeout(() => {
                    alert('恭喜！答案完全正确！');
                }, 300);
            }
        }

        // 检查重复数字
        function checkDuplicates() {
            // 检查行
            for (let row = 0; row < 9; row++) {
                const seen = new Set();
                for (let col = 0; col < 9; col++) {
                    const value = currentBoard[row][col];
                    if (value === 0) continue;

                    if (seen.has(value)) {
                        markDuplicates(row, col, value);
                    } else {
                        seen.add(value);
                    }
                }
            }

            // 检查列
            for (let col = 0; col < 9; col++) {
                const seen = new Set();
                for (let row = 0; row < 9; row++) {
                    const value = currentBoard[row][col];
                    if (value === 0) continue;

                    if (seen.has(value)) {
                        markDuplicates(row, col, value);
                    } else {
                        seen.add(value);
                    }
                }
            }

            // 检查3x3子网格
            for (let boxRow = 0; boxRow < 3; boxRow++) {
                for (let boxCol = 0; boxCol < 3; boxCol++) {
                    const seen = new Set();
                    for (let row = 0; row < 3; row++) {
                        for (let col = 0; col < 3; col++) {
                            const actualRow = boxRow * 3 + row;
                            const actualCol = boxCol * 3 + col;
                            const value = currentBoard[actualRow][actualCol];
                            if (value === 0) continue;

                            if (seen.has(value)) {
                                markDuplicates(actualRow, actualCol, value);
                            } else {
                                seen.add(value);
                            }
                        }
                    }
                }
            }
        }

        // 标记重复的数字
        function markDuplicates(row, col, value) {
            const cell = sudokuGrid.rows[row].cells[col];

            // 只标记用户输入的单元格
            if (initialBoard[row][col] === 0) {
                cell.classList.remove('correct');
                cell.classList.add('incorrect');
            }
        }

        // 重新开始游戏
        function restartGame() {
            if (!currentDifficulty) {
                alert('请先选择难度开始游戏！');
                return;
            }

            startGame(currentDifficulty);
        }

        // 事件监听
        easyBtn.addEventListener('click', () => startGame('easy'));
        mediumBtn.addEventListener('click', () => startGame('medium'));
        hardBtn.addEventListener('click', () => startGame('hard'));
        checkBtn.addEventListener('click', checkSolution);
        restartBtn.addEventListener('click', restartGame);

        // 初始化
        initGrid();

        // 默认开始简单游戏
        startGame('easy');
    });
</script>
</body>
</html>